home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / SW Demo / Demo Source / WindowHandler.c < prev    next >
Encoding:
Text File  |  1994-11-09  |  14.9 KB  |  623 lines  |  [TEXT/MPCC]

  1. // ----------------------------------------------------------------------------------
  2. // WindowHandler.c
  3. // ----------------------------------------------------------------------------------
  4. // Handles all window commands, including window creation and window file i/o.
  5. //
  6. // ----------------------------------------------------------------------------------
  7. // History:
  8. //    8/26/94        Clark Goble    Original
  9. //
  10.  
  11. #include "WindowHandler.h"
  12. #include "TEHandler.h"
  13. #include "Globals.h"
  14.  
  15. void SetWindowBounds(WindowPtr theWindow, Rect newBounds);
  16. Rect GetWindowContentRect(WindowPtr window);
  17. Rect GetWindowStructureRect(WindowPtr window);
  18. void LocalToGlobalRect(Rect *aRect);
  19. Point GetGlobalTopLeft(WindowPtr window);
  20. void CreateDocWindow(void);
  21. void CloseDocWindow(WindowPtr window);
  22. void UpdateDocWindow(WindowPtr updateWindow);
  23. void DoIdle(void);
  24. void DoCloseWindow(register EventRecord *evt, register WindowPtr theWindow);
  25. void DoClickInContent(register EventRecord *evt, register WindowPtr theWindow);
  26. void DoDragWindow(register EventRecord *evt, register WindowPtr theWindow);
  27. void DoGrowWindow(register EventRecord *evt, register WindowPtr theWindow);
  28. void InvalidateScrollbars(WindowPtr theWindow);
  29. void DoZoom(register EventRecord *evt, register WindowPtr theWindow, int part);
  30. void ActivateWindow(register WindowPtr newFrontWindow);
  31. void DeactivateWindow(register WindowPtr newBehindWindow);
  32.  
  33. extern void ErrMsgCode(Str255 msg, short code);
  34.  
  35. // ----------------------------------------------------------------------------------
  36. WindowPtr    gFirstWindow;
  37. WindowPtr    gDocWindow;
  38. CursHandle    gTextCurs;
  39.  
  40. // ----------------------------------------------------------------------------------
  41. // CreateDocWindow
  42. // ----------------------------------------------------------------------------------
  43. // This creates the physical window, the TE record and the like.  It is empty
  44. // after this routine.  It is also in the front (and the global gDocWindow is
  45. // set to it)
  46.  
  47. void CreateDocWindow(void)
  48. {
  49.     WindowPtr    newWindow;
  50.     Rect        viewRect;
  51.     WinDocRecord    **theData;
  52.     
  53.     Rect        vScrollRect;
  54.     
  55.     // create the window
  56.     newWindow = GetNewWindow(rWindowID, nil, (WindowPtr) -1);
  57.     SetPort(newWindow);
  58.     
  59.     if (newWindow == nil)
  60.         return;
  61.     
  62.     // Setup the Window Data
  63.     
  64.     SetWTitle(newWindow, "\pUntitled");        
  65.     theData = (WinDocRecord**) NewHandle(sizeof(WinDocRecord));
  66.     (*theData)->DocWindow = newWindow;
  67.     (*theData)->DocNumber = 0;
  68.     (*theData)->DocName = "\pUntitled";
  69.     (*theData)->vRefNum = 0;
  70.     
  71.     // Setup the Scrollbar
  72.     
  73.     vScrollRect = newWindow->portRect;
  74.     vScrollRect.left = vScrollRect.right - 15;
  75.     vScrollRect.right += 1;
  76.     vScrollRect.bottom -= 14;
  77.     (*theData)->DocVScroll = NewControl( newWindow, &vScrollRect, "\p", TRUE,
  78.              0, 0, 0, 16, 0L);
  79.  
  80.     // Setup the TE View
  81.     
  82.     viewRect = newWindow->portRect;
  83.     viewRect.right -= 15;
  84.     InsetRect(&viewRect, 4, 4);
  85.     (*theData)->DocTE = TENew(&viewRect, &viewRect);
  86.     TEAutoView(true, (*theData)->DocTE);
  87.     (**theData).dirty = FALSE;
  88.     
  89.     if ((*theData)->DocTE == NULL)
  90.         return;
  91.         
  92.     // Save our data in the window
  93.     
  94.     SetWRefCon(newWindow, (long) theData);
  95.     
  96.     // This is the current window
  97.     gDocWindow = newWindow;
  98.     
  99.     SetScrollBar();
  100.     
  101.     
  102. } // CreateDocWindow    
  103.  
  104.  
  105.  
  106. // ----------------------------------------------------------------------------------
  107. // DoSave
  108. // ----------------------------------------------------------------------------------
  109. // This physcially save the text in the data fork and the style in the resource fork.
  110.  
  111. Boolean
  112. DoSave(unsigned char *Name, short vRefNum, TEHandle theTE)
  113. {    
  114.     CharsHandle        theText;
  115.     short            fRefNum;
  116.     long            theTextSize;
  117.     OSErr            err;
  118.  
  119.     // delete possibly extant file
  120.     
  121.     err = FSDelete(Name, vRefNum);
  122.     if ((err != 0) && (err != -43))     // no error or file not found
  123.         return err;
  124.         
  125.     err = Create(Name, vRefNum, 'DLLL', 'TEXT');
  126.     if (err)
  127.         return err;
  128.         
  129.     err = FSOpen(Name, vRefNum, &fRefNum);
  130.     if (err)
  131.         return err;
  132.     err = SetFPos(fRefNum, fsFromStart, 0L);
  133.     if (err)
  134.         return err;
  135.     err = SetEOF(fRefNum, 0L);
  136.     if (err)
  137.         return err;
  138.     
  139.     
  140.     
  141.     // write the text
  142.     theText = TEGetText(theTE);
  143.     theTextSize = GetHandleSize( theText);
  144.     
  145.     HLock(theText);
  146.     err = FSWrite(fRefNum, &theTextSize, *theText);
  147.     if (err)
  148.         return err;
  149.     HUnlock(theText);
  150.  
  151.     err = FSClose(fRefNum);
  152.  
  153.  
  154.     return 0;
  155.     
  156. } // DoSave
  157.  
  158. // ----------------------------------------------------------------------------------
  159. // SaveDocWindowAs
  160. // ----------------------------------------------------------------------------------
  161. // This brings up a SaveAs dialog and then (if selected) saves the window to that
  162. // file.
  163.  
  164. void
  165. SaveDocWindowAs(WindowPtr window)
  166. {    
  167.     WinDocRecord    **theData;
  168.     SFReply            reply;
  169.     Point            where;
  170.     
  171.     short            oldResFile;
  172.  
  173.     oldResFile = CurResFile();
  174.     
  175.     theData = (WinDocRecord**) GetWRefCon(window);
  176.     
  177.     where.h = 100;
  178.     where.v = 60;
  179.     
  180.     SFPutFile( where, "\pSave document as:", "\pUntitled", nil, &reply);
  181.     
  182.     if (!reply.good)
  183.         return;    // cancelled
  184.     
  185.     DoSave(reply.fName, reply.vRefNum, GetTE(window));
  186.     
  187.     (*theData)->vRefNum = reply.vRefNum;
  188.     (*theData)->DocName = reply.fName;
  189.     SetWTitle(window, reply.fName);
  190.     (**theData).dirty = FALSE;
  191.  
  192.     UseResFile( oldResFile );
  193.     
  194.  
  195. } // SaveDocWindowAs
  196.  
  197. // ----------------------------------------------------------------------------------
  198. // SaveDocWindow
  199. // ----------------------------------------------------------------------------------
  200. // If the window has been saved before, this saves it with the data stored in it's
  201. // data table.  Otherwise it calls SaveAs.
  202.  
  203. void
  204. SaveDocWindow(WindowPtr window)
  205. {    
  206.     WinDocRecord    **theData;
  207.     short            oldResFile;
  208.     
  209.     theData = (WinDocRecord**) GetWRefCon(window);
  210.     
  211.     oldResFile = CurResFile();
  212.         
  213.     if ((*theData)->vRefNum == 0)
  214.     {    SaveDocWindowAs(window);
  215.         return;
  216.     }
  217.     
  218.     DoSave((*theData)->DocName, (*theData)->vRefNum, GetTE(window));
  219.  
  220.     (**theData).dirty = FALSE;
  221.     
  222.     UseResFile( oldResFile );
  223.  
  224. }
  225.  
  226. // ----------------------------------------------------------------------------------
  227. // DoOpen
  228. // ----------------------------------------------------------------------------------
  229. // This physically reads in the data and style.  It can be passed the file or, if
  230. // passed nil, it brings up a standard open dialog box to select a file to open.
  231.  
  232.  
  233. OSErr DoOpen(FSSpec *inSpec)
  234. {
  235.     long                theTextSize, sizeRead;
  236.  
  237.     TEHandle            theTE;
  238.     char*                theText;
  239.     WinDocRecord        **theData;
  240.     OSErr                err;
  241.     
  242.     StandardFileReply    reply;
  243.     FSSpec                theFile;
  244.     short                FileRef;
  245.     SFTypeList            theTypes;
  246.     
  247.     theTypes[0] = 'TEXT';
  248.  
  249.     
  250.     if (inSpec)
  251.     {    // was passed the file
  252.         theFile = reply.sfFile = *inSpec;
  253.  
  254.     } else 
  255.     {
  256.         StandardGetFile( nil, 1, theTypes, &reply);
  257.  
  258.         if (!reply.sfGood)
  259.             return false;
  260.         
  261.         theFile = reply.sfFile;
  262.     }
  263.     
  264.     // put up watch while opening
  265.     SetCursor(*GetCursor(watchCursor));
  266.     
  267.     // create the window    
  268.     CreateDocWindow();
  269.     SetWTitle(gDocWindow, theFile.name);
  270.     theData = (WinDocRecord**) GetWRefCon(gDocWindow);
  271.     (*theData)->DocName = theFile.name;
  272.     (*theData)->vRefNum = theFile.vRefNum;
  273.     
  274.     // open up the data fork
  275.     if (err = FSpOpenDF(&reply.sfFile, fsRdPerm, &FileRef))
  276.     {    ErrMsgCode("\pOpening File", err);
  277.         return err;
  278.     } // if    
  279.     
  280.     // load the data
  281.     err = GetEOF(FileRef, &theTextSize);
  282.     
  283.     theTE = GetTE(gDocWindow);
  284.     theText = NewPtr(theTextSize);
  285.     sizeRead = theTextSize;
  286.     
  287.     err = FSRead(FileRef, &sizeRead, (Ptr) theText);
  288.     
  289.     FSClose(FileRef);
  290.     
  291.     TEInsert(theText, sizeRead, theTE);
  292.     DisposePtr(theText);
  293.     
  294.     ShowSelect(theTE, (**theData).DocVScroll);
  295.     SetScrollBar();
  296.     InitCursor();
  297.  
  298.     return 0;
  299. } // DoOpen
  300.  
  301. // ----------------------------------------------------------------------------------
  302. // SaveAsk
  303. // ----------------------------------------------------------------------------------
  304. // This prompts to see if you want to save the file.  Ideally this should only be
  305. // done if the file is dirty.  Right now it always does it.
  306.  
  307.  
  308. short SaveAsk()
  309. {
  310.     
  311.     return Alert( rSaveAskID, nil);
  312.     
  313. }
  314.  
  315.  
  316. // ----------------------------------------------------------------------------------
  317. // OpenDocWindow
  318. // ----------------------------------------------------------------------------------
  319. // Opens a doc window
  320.  
  321.  
  322. void 
  323. OpenDocWindow()
  324. {
  325.     // open a new window
  326.     DoOpen(nil);
  327. }
  328.  
  329. // ----------------------------------------------------------------------------------
  330. // CloseDocWindow
  331. // ----------------------------------------------------------------------------------
  332. // Closes a doc window.
  333.  
  334. void 
  335. CloseDocWindow(WindowPtr window)
  336. {
  337.     short    answer;
  338.     WinDocRecord **data;
  339.     
  340.     data =  (WinDocRecord**) GetWRefCon(window);
  341.  
  342.     if ( (**data).dirty )
  343.     {
  344.         answer = SaveAsk();
  345.         if (answer == kACancel)
  346.             return;
  347.         if (answer == kASave)
  348.             SaveDocWindow(window);
  349.     }
  350.  
  351.     
  352.     DisposeControl((*data)->DocVScroll);
  353.     TEDispose(GetTE(window));
  354.     DisposeHandle( (Handle) data );
  355.     DisposeWindow(window);
  356.     
  357.     // make the new front window the current window.
  358.     gDocWindow = FrontWindow();
  359.     
  360. } // CloseDocWindow
  361.  
  362.  
  363.  
  364. // ----------------------------------------------------------------------------------
  365. // UpdateDocWindow    
  366. // ----------------------------------------------------------------------------------
  367. // Handle a document Updata event (Not used right now)
  368.  
  369. void UpdateDocWindow(WindowPtr updateWindow)
  370. {    
  371.  
  372. }
  373.  
  374.  
  375. // ----------------------------------------------------------------------------------
  376. // DoIdle    
  377. // ----------------------------------------------------------------------------------
  378. // Things to do at idle time (once through the event loop)
  379. // (Not used right now)
  380.  
  381. void
  382. DoIdle(void)
  383. {
  384. }
  385.  
  386. // ----------------------------------------------------------------------------------
  387. // DoCloseWindow
  388. // ----------------------------------------------------------------------------------
  389. // Close a window.
  390.  
  391. void DoCloseWindow(register EventRecord *evt, register WindowPtr theWindow)
  392. {
  393.     if (TrackGoAway(theWindow,evt->where)) 
  394.     {
  395.  
  396.         if ( theWindow == nil )
  397.         return;
  398.             
  399.         if ( ((WindowPeek) theWindow)->windowKind < 0 ) 
  400.         {    // system window
  401.             CloseDeskAcc( ( (WindowPeek) theWindow )->windowKind );
  402.             
  403.         } else if ( ((WindowPeek) theWindow)->windowKind == dialogKind) 
  404.         {    // dialog window
  405.             HideWindow(theWindow);
  406.             
  407.         } else if (((WindowPeek) theWindow)->windowKind >= userKind)  
  408.         {
  409.             // app window
  410.             CloseDocWindow(theWindow);
  411.         }// if/else/else
  412.     } // if
  413.  
  414. } // DoCloseWindow
  415.  
  416. // ----------------------------------------------------------------------------------
  417. // DoClickInContent
  418. // ----------------------------------------------------------------------------------
  419. // Handle a click in a window.
  420.  
  421. void DoClickInContent(register EventRecord *evt, register WindowPtr theWindow)
  422. {
  423.     int                part;
  424.     ControlHandle    theControl;
  425.     Point            pt;
  426.     GrafPtr            saveport;
  427.     TEHandle        theTE;
  428.     Boolean            theShiftKey;
  429.     
  430.     if(theWindow!=FrontWindow()) 
  431.     {
  432.         SelectWindow(theWindow);
  433.     } else 
  434.     {
  435.         GetPort(&saveport);
  436.         SetPort(theWindow);
  437.         pt = evt->where;
  438.         GlobalToLocal(&pt);
  439.         
  440.         if( (part = FindControl(pt,theWindow,&theControl)) != 0) 
  441.         {
  442.             DoControl(theWindow, theControl, part, pt);
  443.         } else 
  444.         {    // Clicked in TE
  445.             // update global window for use by scroll function
  446.             gDocWindow = theWindow;
  447.             theTE = GetTE(theWindow);
  448.             theShiftKey = ( (evt->modifiers & shiftKey) > 0);
  449.             
  450.             TEClick(pt, theShiftKey, theTE);
  451.             
  452.         } // if/else
  453.         
  454.         SetPort(saveport);
  455.     } // if/else
  456. } // DoClickInContent
  457.  
  458.  
  459.  
  460. // ----------------------------------------------------------------------------------
  461. // DoDragWindow
  462. // ----------------------------------------------------------------------------------
  463. // Drag a window.
  464.  
  465. void DoDragWindow(register EventRecord *evt, register WindowPtr theWindow)
  466. {
  467.     DragWindow(theWindow,evt->where,&qd.screenBits.bounds);
  468.     
  469. } // DoDragWindow
  470.  
  471. // ----------------------------------------------------------------------------------
  472. // DoGrowWindow
  473. // ----------------------------------------------------------------------------------
  474. // Resize a window.
  475.  
  476. void DoGrowWindow(register EventRecord *evt, register WindowPtr theWindow)
  477. {
  478.     long            newSize;
  479.     int                newHeight,newWidth;
  480.     Rect            SizeLimits;
  481.     GrafPtr            oldPort;
  482.     TEHandle        theTE;
  483.     WinDocRecord    **theData;
  484.     ControlHandle    theControl;
  485.     
  486.     theData = (WinDocRecord**) GetWRefCon(theWindow);
  487.     theControl = (*theData)->DocVScroll;
  488.     
  489.     SetRect(&SizeLimits, 30,50,32767,32767);
  490.     
  491.     newSize = GrowWindow(theWindow,evt->where,&SizeLimits);
  492.     if (newSize == 0L)
  493.         return;
  494.     
  495.     newHeight = HiWord(newSize);
  496.     newWidth = LoWord(newSize);
  497.     
  498.     GetPort(&oldPort);
  499.     SetPort(theWindow);
  500.     
  501.     SizeWindow(theWindow,newWidth,newHeight,true);
  502.     
  503.     // resize the text edit pane
  504.  
  505.     theTE = GetTE(theWindow);
  506.     TEAdjustView(theWindow, theTE);
  507.     
  508.     InvalRect( &(theWindow->portRect) );    // mark everything for an update
  509.     
  510.     // resize the scrollbars
  511.     SizeScroll(theControl, theWindow);
  512.     SetScrollBar();
  513.     
  514.     
  515.     SetPort(oldPort);
  516.     
  517. } // DoGrowWindow
  518.  
  519.  
  520. // ----------------------------------------------------------------------------------
  521. // InvalidateScrollbars    
  522. // ----------------------------------------------------------------------------------
  523. // Take care of scrollbars during window sizing
  524.  
  525. void InvalidateScrollbars(WindowPtr theWindow)
  526. {
  527.     Rect    tempRect;
  528.  
  529.     SetPort(theWindow);
  530.  
  531.     tempRect = theWindow->portRect;
  532.     tempRect.left = tempRect.right - 15;
  533.     InvalRect(&tempRect);
  534.     EraseRect(&tempRect);
  535.  
  536.     tempRect = theWindow->portRect;
  537.     tempRect.top = tempRect.bottom - 15;
  538.     InvalRect(&tempRect);
  539.     EraseRect(&tempRect);
  540.     
  541. } // InvalidateScrollbars
  542.  
  543.  
  544. // ----------------------------------------------------------------------------------
  545. // GetTE
  546. // ----------------------------------------------------------------------------------
  547. // This gets the TE handle from the window's ref data.
  548.  
  549. TEHandle GetTE(WindowPtr window)
  550. {    
  551.     WinDocRecord    **theData;
  552.     
  553.     theData = (WinDocRecord**) GetWRefCon(window);
  554.     return (*theData)->DocTE;
  555.     
  556. } // GetTE
  557.  
  558. // ----------------------------------------------------------------------------------
  559. // DoZoom
  560. // ----------------------------------------------------------------------------------
  561. // Zooms a window between sysem size and user size.
  562.  
  563. void DoZoom(register EventRecord *evt, register WindowPtr theWindow, int part)
  564. {
  565.     
  566.     GrafPtr savePort;
  567.     
  568.     GetPort(&savePort);
  569.     SetPort(theWindow);
  570.     
  571.     if(TrackBox(theWindow,evt->where,part)) {
  572.         ZoomWindow(theWindow,part,true);
  573.     }
  574.     
  575.     SetPort(savePort);
  576. }
  577.  
  578. // ----------------------------------------------------------------------------------
  579. // ActivateWindow
  580. // ----------------------------------------------------------------------------------
  581. // A window is becoming active.
  582.  
  583. void ActivateWindow(register WindowPtr    newFrontWindow)
  584. {    
  585.     
  586.     TEActivate( GetTE(newFrontWindow) );
  587.     gDocWindow = newFrontWindow;
  588.     
  589. } // ActivateWindow
  590.  
  591. // ----------------------------------------------------------------------------------
  592. // DeactivateWindow
  593. // ----------------------------------------------------------------------------------
  594. // A window is being deactivated.
  595.  
  596. void DeactivateWindow(register WindowPtr    newBehindWindow)
  597. {
  598.     TEDeactivate ( GetTE(newBehindWindow) );
  599. } // DeactivateWindow
  600.  
  601. void WindowCursor(WindowPtr theWindow)
  602. {
  603.     Point        theMouse;
  604.     TEHandle    theTE;
  605.     Rect        theView;
  606.     GrafPtr        oldPort;
  607.     
  608.     
  609.     GetPort(&oldPort);
  610.     SetPort(theWindow);
  611.     
  612.     GetMouse(&theMouse);
  613.     theTE = GetTE(theWindow);
  614.     theView = (*theTE)->viewRect;
  615.     
  616.     if (PtInRect(theMouse, &theView))    // in text view
  617.         SetCursor(*gTextCurs);
  618.     else
  619.         InitCursor();
  620.     
  621.     SetPort(oldPort);
  622. } // DeactivateWindow
  623.